package com.zj.service;

import cn.hutool.core.thread.ThreadUtil;
import cn.hutool.crypto.digest.MD5;
import com.zj.entity.Camera;
import com.zj.thread.MediaRecodeOrTransfer;
import io.netty.channel.ChannelHandlerContext;
import org.springframework.stereotype.Service;

import java.util.concurrent.ConcurrentHashMap;

/**
 * 媒体服务
 *
 * @author ZJ
 */
@Service
public class MediaService {

    // 缓存流转换线程
    public static ConcurrentHashMap<String, MediaRecodeOrTransfer> cameras = new ConcurrentHashMap<>();

    /**
     * @param camera
     * @param ctx
     * @param autoClose
     */
    public void playForHttp(Camera camera, ChannelHandlerContext ctx, boolean autoClose) {

        // 区分不同媒体
        String mediaKey = MD5.create().digestHex(camera.getUrl());

        if (cameras.containsKey(mediaKey)) {
            MediaRecodeOrTransfer mediaConvert = cameras.get(mediaKey);
            cameras.put(mediaKey, mediaConvert);
            mediaConvert.addHttpClient(ctx);
        } else {
            MediaRecodeOrTransfer mediaConvert = new MediaRecodeOrTransfer(camera, autoClose);
            cameras.put(mediaKey, mediaConvert);
            ThreadUtil.execute(mediaConvert);
            mediaConvert.addHttpClient(ctx);
        }
    }

    public void playForWs(Camera camera, ChannelHandlerContext ctx, boolean autoClose) {

        // 区分不同媒体
        String mediaKey = MD5.create().digestHex(camera.getUrl());

        if (cameras.containsKey(mediaKey)) {
            MediaRecodeOrTransfer mediaConvert = cameras.get(mediaKey);
            cameras.put(mediaKey, mediaConvert);
            mediaConvert.addWsClient(ctx);
        } else {
            MediaRecodeOrTransfer mediaConvert = new MediaRecodeOrTransfer(camera, autoClose);
            cameras.put(mediaKey, mediaConvert);
            ThreadUtil.execute(mediaConvert);
            mediaConvert.addWsClient(ctx);
        }
    }

    /**
     * api拉流
     *
     * @param camera
     */
    public void playForApi(Camera camera) {

        // 区分不同媒体
        String mediaKey = MD5.create().digestHex(camera.getUrl());

        if (!cameras.containsKey(mediaKey)) {
            MediaRecodeOrTransfer mediaConvert = new MediaRecodeOrTransfer(camera, true);
            cameras.put(mediaKey, mediaConvert);
            ThreadUtil.execute(mediaConvert);
        }
    }

    /**
     * 关闭流
     *
     * @param camera
     */
    public void closeForApi(Camera camera) {

        // 区分不同媒体
        String mediaKey = MD5.create().digestHex(camera.getUrl());

        if (cameras.containsKey(mediaKey)) {
            MediaRecodeOrTransfer mediaConvert = cameras.get(mediaKey);
            mediaConvert.setRuning(false);
            cameras.remove(mediaKey);
        }
    }


    public void closeAllForApi() {
        ConcurrentHashMap.KeySetView<String, MediaRecodeOrTransfer> keys = cameras.keySet();
        for (String mediaKey : keys) {
            MediaRecodeOrTransfer mediaConvert = cameras.get(mediaKey);
            mediaConvert.setRuning(false);
            cameras.remove(mediaKey);
        }
    }
}
